<template>
	<view class="content">
	<view class="niceui-color-picker" @click="show" :style="{height:size+'px'}">
		<view class="niceui-color-picker__trigger" :style="{height:size+'px',width:size+'px'}">
			<text class="niceui-color-picker__color">
				<text class="niceui-color-picker__color-inner" :style="{ background: colorName }"></text>
			</text>
			<text class="niceui-color-picker__icon niceui-icon-arrow-down" style="" v-if="colorName"> > </text>
			<text class="niceui-color-picker__icon niceui-icon-close" style="color:#888;" v-if="!colorName"> x </text>
		</view>
	</view>
	<view class="color-picker" v-if="showFlag">
		<view class="picker-main">
			<view class="picker_color">
				<view class="color-view" @touchstart="pickColor" @touchmove="pickColor" :style="{ backgroundColor: 'hsl(' + hueView.H + ', 100%, 50%)' }">
					<text class="anchor" :style="{ top: colorView.anchorTop + 'px', left: colorView.anchorLeft + 'px' }"></text>
				</view>
				<view class="hue-view" @touchstart="pickHue" @touchmove="pickHue">
					<text class="anchor" :style="{ top: hueView.anchorTop + 'px' }"></text>
				</view>
			</view>
			<view class="picker__toolbar">
				<view class="color-name">{{ colorName }}</view>
				<view class="btn__group">
					<button class="btn__cancel" @click="cancel">取消</button>
					<button class="btn__confirm" @click="confirm">确定</button>
				</view>
			</view>
		</view>
	</view>
	</view>
</template>

<script>
export default {
	props:{
		size:{
			type:Number,
			default:40
		}
	},
	data() {
		return {
			showFlag:false,
			hueView: {},
			colorView: {},
			colorName:uni.getStorageSync('colorInfo')?uni.getStorageSync('colorInfo').colorName:'',
			hueTop: 0.5, // 色相选择器初始位置 [0, 1]
			anchorTop: 0.5, // 颜色选择器初始 top [0, 1]
			anchorLeft: 0.5, // 颜色选择器初始 left [0, 1]
		};
	},
	mounted() {
		
	},
	methods: {
		show(){
			//setTimeout(()=>{
				this.showFlag = true
			//},20)
			this.$nextTick(()=>{ //必须加这个
				Promise.all([this.getHueViewOffset(), this.getColorViewOffset()]).then(() => {
					
					let info = uni.getStorageSync('colorInfo')
					if(info&&JSON.stringify(info)!='{}'){
						this.hueView.anchorTop = info.anchorTop
						this.hueView.height = info.height
						this.colorView.S = info.S
						this.colorView.L = info.L
						this.hueView.H = info.hueViewH
						this.colorView.anchorTop = info.colorViewAnchorTop,
						this.colorView.anchorLeft = info.colorViewAnchorLeft,
						this.hueView.anchorTop = info.hueViewAnchorTop
						this.colorName = info.colorName // 根据 HLS 计算 RGB 字符串
					}else{
						this.colorName = this.getColorString() // 根据 HLS 计算 RGB 字符串
					}
				})
			})
		},
		getHueViewOffset() { // 获取色相选择区域尺寸
			const hue = 0.5 // 色相选择器初始位置 [0, 1]
			return new Promise(resolve => uni.createSelectorQuery().in(this).select('.hue-view').boundingClientRect(data => {
					console.log('getHueViewOffset----',data)
					this.hueView = {
						...data, 
						anchorTop: data.height * this.hueTop, 
						H: this.hueTop * 350,
					}
					resolve()
				}).exec()
			)
		},
		getColorViewOffset() { // 获取颜色选择区域尺寸
			return new Promise(resolve => uni.createSelectorQuery().in(this).select('.color-view').boundingClientRect(data => {
					console.log('getColorViewOffset------',data)
					this.colorView = {
						...data, 
						anchorTop: data.height * this.anchorTop, 
						anchorLeft: data.width * this.anchorLeft, 
						S: this.anchorLeft, 
						L: (1 - this.anchorLeft * 0.5) - this.anchorTop / (this.anchorLeft + 1)
					}
					resolve()
				}).exec()
			)
		},
		confirm() {
			this.$emit('getColor',this.colorName)
			//缓存，下次打开使用
			uni.setStorageSync('colorInfo',{
				anchorTop:this.hueView.anchorTop,
				height:this.hueView.height,
				S:this.colorView.S,
				L:this.colorView.L,
				hueViewH:this.hueView.H,
				colorViewAnchorTop:this.colorView.anchorTop,
				colorViewAnchorLeft:this.colorView.anchorLeft,
				hueViewAnchorTop:this.hueView.anchorTop,
				colorName:this.colorName
			})
			this.showFlag = false
		},
		cancel(){
			this.$emit('getColor','')
			this.showFlag = false
		},
		getColorString() { // 获取 RGB 颜色字符串
			const arr = this.hslToRgb(this.hueView.anchorTop / this.hueView.height, this.colorView.S, this.colorView.L)
			const r = arr[0].toString(16).length === 1 ? `0${arr[0].toString(16)}` : arr[0].toString(16)
			const g = arr[1].toString(16).length === 1 ? `0${arr[1].toString(16)}` : arr[1].toString(16)
			const b = arr[2].toString(16).length === 1 ? `0${arr[2].toString(16)}` : arr[2].toString(16)
			return `#${r.toUpperCase()}${g.toUpperCase()}${b.toUpperCase()}`
		},
		pickColor(e) { // 选择颜色
			const top = e.touches[0].pageY - this.colorView.top
			const left = e.touches[0].pageX - this.colorView.left
			if (top < 0) {
				this.colorView.anchorTop = 0
			} else if (top > this.colorView.height) {
				this.colorView.anchorTop = this.colorView.height
			} else {
				this.colorView.anchorTop = e.touches[0].pageY - this.colorView.top
			}
			if (left < 0) {
				this.colorView.anchorLeft = 0
			} else if (left > this.colorView.width) {
				this.colorView.anchorLeft = this.colorView.width
			} else {
				this.colorView.anchorLeft = e.touches[0].pageX - this.colorView.left
			}
			this.colorView.S = this.colorView.anchorLeft / this.colorView.width
			this.colorView.L = this.floor((1 - this.colorView.S * 0.5) - this.colorView.anchorTop / this.colorView.height / (this.colorView.S + 1))
			this.colorName = this.getColorString() // 根据 HLS 计算 RGB 字符串
		},
		pickHue(e) { // 选择色相
			if (e.touches[0].pageY >= this.hueView.top && e.touches[0].pageY <= this.hueView.bottom) {
				this.hueView.anchorTop = e.touches[0].pageY - this.hueView.top
				this.hueView.H = this.hueView.anchorTop / this.hueView.height * 350
				this.colorName = this.getColorString() // 根据 HLS 计算 RGB 字符串
			}
		},
		floor(num) {
			return num < 0.09 ? 0 : num
		},
		hslToRgb(h, s, l) {  // HSL 转 RGB 方法
			var r, g, b;
			if(s == 0) {
				r = g = b = l; // achromatic
			} else {
				var hue2rgb = function hue2rgb(p, q, t) {
					if(t < 0) t += 1;
					if(t > 1) t -= 1;
					if(t < 1/6) return p + (q - p) * 6 * t;
					if(t < 1/2) return q;
					if(t < 2/3) return p + (q - p) * (2/3 - t) * 6;
					return p;
				}
				var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
				var p = 2 * l - q;
				r = hue2rgb(p, q, h + 1/3);
				g = hue2rgb(p, q, h);
				b = hue2rgb(p, q, h - 1/3);
			}
			return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255)];
		}
	} 
}
</script>

<style lang="scss" scoped>
	.content{
		display: flex;
		flex-direction: column;
		align-items: center;
	}
		.niceui-color-picker {
				display: inline-block;
				position: relative;
				line-height: normal;
				height: 40px;
		
			.niceui-color-picker__trigger {
				display: inline-block;
				box-sizing: border-box;
				height: 40px;
				width: 40px;
				padding: 4px;
				border: 1px solid #e6e6e6;
				border-radius: 4px;
				font-size: 0;
				position: relative;
				cursor: pointer;
			
				.niceui-color-picker__color {
					position: relative;
					display: block;
					box-sizing: border-box;
					border: 1px solid #999;
					border-radius: 2px;
					width: 100%;
					height: 100%;
					text-align: center;
				
					.niceui-color-picker__color-inner {
						position: absolute;
						left: 0;
						top: 0;
						right: 0;
						bottom: 0;
					}
				}
				
				.niceui-color-picker__icon {
					display: inline-block;
					width: 100%;
					color: #fff;
					text-align: center;
				}
				.niceui-color-picker__icon {
					font-size: 28rpx;
					position: absolute;
					top: 48%;
					left: 49%;
					transform: translate3d(-50%,-50%,0) scale(1.3,1);
				}
				.niceui-icon-arrow-down{
					top: 50%;
					left: 51%;
					font-size: 24rpx;
					transform: translate3d(-50%,-50%,0) rotate(90deg) scale(0.8,1.6);
				}
			}
		}
		.color-picker {
			display: flex;
			align-items: center;
			flex-direction: column;
			justify-content: center;
			position: absolute;
			top:180rpx;
			left:70rpx;
			width: 614rpx;
			
			.picker-main{
				padding: 12rpx;
				box-sizing: content-box;
				background-color: #fff;
				border: 1px solid #ebeef5;
				border-radius: 10rpx;
				box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
				.picker_color{
					display: flex;
					.hue-view {
						// transform: rotate(90deg);
						height: 350rpx;
						width: 28rpx;
						margin: 0rpx 0;
						margin-left: 20rpx;
						position: relative;
						background: linear-gradient(to bottom, #f00, #ff0, #0f0, #0ff, #00f, #f0f, #f00);
						.anchor {
							height: 12rpx;
							width: 100%;
							position: absolute;
							background: #FFFFFF;
							// transform: translate(-50%);
							box-shadow: 0 0 2rpx rgba(0, 0, 0, 0.6);
						}
					}
					.color-view {
						width: 570rpx;
						height: 350rpx;
						position: relative;
						&::before,
						&::after {
							content: '';
							top: 0;
							left: 0;
							width: 100%;
							height: 100%;
							position: absolute;
						}
						&::before {
							background: linear-gradient(to right, white, transparent);
						}
						&::after {
							background: linear-gradient(to top, black, transparent);
						}
						.anchor {
							z-index: 1;
							width: 24rpx;
							height: 24rpx;
							border-radius: 50%;
							position: absolute;
							border: 4rpx solid #FFFFFF;
							background: rgba(0, 0, 0, .3);
							transform: translate(-50%, -50%);
						}
					}
				}
			}
			
			.picker__toolbar{
				display: flex;
				justify-content: space-between;
				width: 614rpx;
				height: 80rpx;
				.color-name {
					border: solid 1px #eee;
					border-radius: 10rpx;
					padding-left: 20rpx;
					width: 300rpx;
					height: 60rpx;
					margin: 20rpx 0;
					font-size: 28rpx;
					font-weight: bold;
					color:#666;
					display: flex;
					justify-content: flex-start;
					align-items: center;
				}
				.btn__group{
					display: flex;
					justify-content: flex-end;
					button{
						margin: 20rpx 0;
						height: 60rpx;
						line-height: 60rpx;
						width: 130rpx;
						font-size: 26rpx;
						background-color: #fff;
					}
					.btn__cancel{
						margin-right: 20rpx;
					}
				}
			}
		}
	
</style>